/** creates a random JSON tree and echoes it */
#include <assert.h>
#include <time.h>
#include "json.h"

static  JSONNodePtr makeRandJSON(int *count);

static  JSONNodePtr makeRandString(int *count)
	{
	*count--;
	return JSONNodeNewString("hello");
	}



static  JSONNodePtr makeRandArray(int *count)
	{
	JSONNodePtr array= JSONNodeArrayNew();
	int i=0;
	int n_item=4+rand()%10;
	if(array==NULL) return NULL;
	for(i=0;i<n_item;++i)
		{
		JSONNodePtr item= makeRandJSON(count);
		if(JSONNodeArrayAppend(array,item)!=1)
			{
			JSONNodeFree(item);
			JSONNodeFree(array);
			return NULL;
			}
		}
	return array;
	}
	
static  JSONNodePtr makeRandObject(int *count)
	{
	JSONNodePtr node;
	char name[7]="field_";
	int i=0;
	int n_item=5+rand()%5;
	//create an object
	node = JSONNodeObjectNew();
	if(node==NULL) return NULL;
	//fill the object
	for(i=0;i<n_item;++i)
		{
		JSONObjetEntryPtr entry;
		name[5]='0'+i;
		entry= JSONObjetEntryNew(
			JSONNodeNewString(name),
			makeRandJSON(count)
			);
		
		if(entry==NULL || JSONNodeObjectPut(node,entry)!=1)
			{
			JSONObjetEntryFree(entry);
			JSONNodeFree(node);
			return NULL;
			}
		}
	return node;
	}

static  JSONNodePtr makeRandJSON(int *count)
	{
	int n=rand()%(*count<0 ? 5:12);//make only terminals if <0
	*count--;
	switch(n)
		{
		case 0: return JSONNodeNewNull();
		case 1: return JSONNodeNewInteger(rand());
		case 2: return JSONNodeNewBoolean((char)(*count%2));
		case 3: return JSONNodeNewFloating(*count/(1.0+rand()));
		case 4: return makeRandString(count);
		case 5: return makeRandObject(count);
		default: return makeRandArray(count);
		}
	assert(0);
	return NULL;
	}


int main(void)
	{
	int count=1000;
	srand(time(0));
	JSONNodePtr root= makeRandObject(&count);
	if(root!=NULL)
		{
		
		JSONPrint(stdout,root);
		fputc('\n',stdout);
		JSONNodeFree(root);
		}
	return 0;
	}